#ifndef _DOHOME_HAL_UART_H_
#define _DOHOME_HAL_UART_H_

#include <dohome_type.h>
#include <dohome_error_code.h>

typedef enum {
    DOHOME_UART0    = 0x00,
    DOHOME_UART1    = 0x01,
    DOHOME_UART2    = 0x02,
    DOHOME_UART3    = 0x03,
    DOHOME_UART_MAX = 0x04,
} dohome_uart_port_t;

typedef enum {
    DOHOME_UART_DATA_5_BITS   = 0x0,    /*!< word length: 5bits*/
    DOHOME_UART_DATA_6_BITS   = 0x1,    /*!< word length: 6bits*/
    DOHOME_UART_DATA_7_BITS   = 0x2,    /*!< word length: 7bits*/
    DOHOME_UART_DATA_8_BITS   = 0x3,    /*!< word length: 8bits*/
    DOHOME_UART_DATA_BITS_MAX = 0x4,
} dohome_uart_word_length_t;

/**
 * @brief UART stop bits number
 */
typedef enum {
    DOHOME_UART_STOP_BITS_1   = 0x1,  /*!< stop bit: 1bit*/
    DOHOME_UART_STOP_BITS_1_5 = 0x2,  /*!< stop bit: 1.5bits*/
    DOHOME_UART_STOP_BITS_2   = 0x3,  /*!< stop bit: 2bits*/
    DOHOME_UART_STOP_BITS_MAX = 0x4,
} dohome_uart_stop_bits_t;

/**
 * @brief UART parity constants
 */
typedef enum {
    DOHOME_UART_PARITY_DISABLE  = 0x0,  /*!< Disable UART parity*/
    DOHOME_UART_PARITY_EVEN     = 0x2,  /*!< Enable UART even parity*/
    DOHOME_UART_PARITY_ODD      = 0x3,  /*!< Enable UART odd parity*/
    DOHOME_UART_PARITY_MAX      = 0x4
} dohome_uart_parity_t;

/**
 * @brief UART hardware flow control modes
 */
typedef enum {
    DOHOME_UART_HW_FLOWCTRL_DISABLE = 0x0,   /*!< disable hardware flow control*/
    DOHOME_UART_HW_FLOWCTRL_RTS     = 0x1,   /*!< enable RX hardware flow control (rts)*/
    DOHOME_UART_HW_FLOWCTRL_CTS     = 0x2,   /*!< enable TX hardware flow control (cts)*/
    DOHOME_UART_HW_FLOWCTRL_CTS_RTS = 0x3,   /*!< enable hardware flow control*/
    DOHOME_UART_HW_FLOWCTRL_MAX     = 0x4,
} dohome_uart_hw_flowcontrol_t;

typedef struct {
    DOHOME_UINT16_T baud_rate;
    dohome_uart_word_length_t data_bits;
    dohome_uart_stop_bits_t stop_bits;
    dohome_uart_parity_t parity; 
    dohome_uart_hw_flowcontrol_t flow_ctrl;
} dohome_uart_cfg_t;

typedef struct {
    dohome_gpio_t tx_io;
    dohome_gpio_t rx_io;
    dohome_gpio_t rts_io;
    dohome_gpio_t cts_io;
} dohome_uart_pin_cfg_t;

typedef void (*dohome_uart_recv_cb_t)(dohome_uart_port_t port, DOHOME_CHAR_T *data, DOHOME_UINT16_T len);

void dohome_hal_putc(DOHOME_CONST DOHOME_CHAR_T c);

dohome_op_ret dohome_hal_uart_init(dohome_uart_port_t port, dohome_uart_cfg_t uart_cfg, dohome_uart_recv_cb_t recv_cb);

dohome_op_ret dohome_hal_uart_deinit(dohome_uart_port_t port);

dohome_op_ret dohome_hal_uart_set_pin(dohome_uart_port_t port, dohome_uart_pin_cfg_t pin_cfg);

DOHOME_UINT16_T dohome_hal_uart_send(dohome_uart_port_t port, DOHOME_CHAR_T *data, DOHOME_UINT16_T len);

#endif // _DOHOME_HAL_UART_H_